/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bluetooth;

import gui.BluetoothCliente;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;
import javax.microedition.lcdui.Choice;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.List;

/**
 *
 * @author Nicolas Caceres
 */
public class Peer implements DiscoveryListener{
    
    private String nombre;
    
    private String clave;
    
    private ArrayList archivos_compartidos;
    
    private List lista_compartidos;
    
    /****************************************************/
    /** Creates a new instance of ClientServer */
    private DiscoveryAgent agente;
    private Vector dispositivos;
    private Vector servicios;
    private Vector dispositivosServiciosId;
    private BluetoothCliente midlet;
    private boolean isReady;
    private String mensaje;
    private static final int ATRIBUTO_LISTADO=0x0001; // Número mágico.
    private static final int[] ATRIBUTOS = new int[] { ATRIBUTO_LISTADO };
    public static final UUID SERVICIO_LISTADO = new UUID(0x2345);
    private static final UUID[] SERVICIOS = new UUID[] { SERVICIO_LISTADO};
    /***************************************************/
    
     
    /**
     * Construjctor de la clase Peer 
     */
    public Peer(){
        
    }
        
    /**
     * Conectarse a la red bluetooth
     * @return 
     */
    public boolean conectar()
    {
        return false;
    }
    
    /**
     * comparte un archivo a los demas peers
     * @param arch 
     */
    public void comnpartirArchivo(Archivo arch)
    {
        if(archivos_compartidos == null)
        {
            archivos_compartidos= new ArrayList();
            Archivo a= new Archivo();
            a.setNombre("archivo1.txt");
            a.setRuta("ruta");
             Archivo b= new Archivo();
            b.setNombre("archivo2.txt");
            b.setRuta("ruta2");
             Archivo c= new Archivo();
            c.setNombre("archivo3.txt");
            c.setRuta("ruta3");
            archivos_compartidos.add(a);
            archivos_compartidos.add(b);
            archivos_compartidos.add(c);          
            
        }
        else {
            archivos_compartidos.add(arch);
        }
        
    }
    /*
    public List darArchivosCompartidos()
    {
        if (lista_compartidos == null) {//GEN-END:MVDGetBegin2
            // Insert pre-init code here
            lista_compartidos = new List(null, Choice.IMPLICIT, new String[] {//GEN-BEGIN:MVDGetInit2
                "No hay Archivos Compartidos"
                
            }, new Image[] {
                null,
                null,
                null
            });
            //lista_compartidos.setCommandListener(this);
            /*lista_compartidos.setSelectedFlags(new boolean[] {
                false,
                false,
                false
            });*///GEN-END:MVDGetInit2
            /*// Insert post-init code here
        }//GEN-BEGIN:MVDGetEnd2
        return lista_compartidos; 
    }*/
    
    public void publicarArchivosRed()
    {
        
    }
    
    public ArrayList getArchivos_compartidos() {
        return archivos_compartidos;
    }

    public void setArchivos_compartidos(ArrayList archivos_compartidos) {
        this.archivos_compartidos = archivos_compartidos;
    }

    public String getClave() {
        return clave;
    }

    public void setClave(String clave) {
        this.clave = clave;
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }
    
/************/
    


    /**
     * Constructor que detecta el dispositivo de bluetooth local, luego coloca el
     * dispositivo en General Discoverable Mode (General/Unlimited Inquiry Access Code)
     * y luego crea un objeto que encapsule la funcionalidad SDAP.
     * @param midlet 
     * @throws BluetoothStateException
     */
    public Peer(BluetoothCliente midlet) throws BluetoothStateException {
        this.midlet = midlet;
        midlet.clearLista();
        dispositivos = new Vector();
        servicios = new Vector();
        dispositivosServiciosId=new Vector();
        isReady=false;
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        localDevice.setDiscoverable(DiscoveryAgent.GIAC);
        agente = localDevice.getDiscoveryAgent();
    }

    /**
     * Comienza la búsqueda de disposivitos y servicios bluetooth.
     * @throws BluetoothStateException
     */
    public void startBusquedaDispositivos() throws BluetoothStateException {
        setMensaje("Comenzando búsqueda de dispositivos bluetooth.");
        agente.startInquiry(DiscoveryAgent.GIAC, this);
    }

    /**
     * Método que se ejecuta cuando se encuentra un disposivito bluetooth,
     * informa el dispositvo bluetooth encontrado y lo agrega al vector
     * de dispositivos encontrados; el disposivito es un objeto RemoteDevice.
     * @param rd
     * @param dc
     */
    public void deviceDiscovered(RemoteDevice rd, DeviceClass dc) {

        setMensaje("Dispositivo Bluetooth encontrado.");
        dispositivos.addElement(rd);

        try
        {
            System.out.println(rd.getFriendlyName(true));
        } 
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

    /**
     * Método que se ejecuta cuando la búsqueda de disposivitos y servicios
     * bluetooth ha finalizado, notificando la situación y mostrando los
     * dispositivos bluetooth encontrados, almacenados en un vector.
     * @param i
     */
    public void inquiryCompleted(int i) {

        setMensaje("Se ha completado la busqueda de dispositivos bluetooth.");
        System.out.println(mensaje);
        isReady=true;

        try
        {
            setListaDispositivos();
        } 
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
    }

    /**
     * Método que se ejecuta cuando se buscan servicios bluetooth.
     * @param i
     * @param i1
     */
    public void serviceSearchCompleted(int transID, int respCode) {

        mensaje=null;
        
        switch (respCode)
        {
            case DiscoveryListener.SERVICE_SEARCH_COMPLETED:
                mensaje="Búsqueda completada con normalidad";
                break;

            case DiscoveryListener.SERVICE_SEARCH_TERMINATED:
                mensaje="Búsqueda cancelada";
                break;

            case DiscoveryListener.SERVICE_SEARCH_DEVICE_NOT_REACHABLE:
                mensaje="Dispositivo no alcanzable";
                break;

            case DiscoveryListener.SERVICE_SEARCH_NO_RECORDS:
                mensaje="No se encontraron registros de servicio";
                break;

            case DiscoveryListener.SERVICE_SEARCH_ERROR:
                mensaje="Error en la búsqueda";
                break;
        }

    }

    /**
     * Método que se ejecuta cuando se encuentran servicios bluetooth.
     * @param i
     * @param srs
     */
    public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {

        ServiceRecord service = null;

        for (int i = 0; i < servRecord.length; i++)
        {
            service = servRecord[i];
            String url = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
            StreamConnection connection = null;
            DataInputStream in = null;
            DataOutputStream out = null;

            try
            {
                connection = (StreamConnection) Connector.open(url);
                in = connection.openDataInputStream();
                out = connection.openDataOutputStream();
                out.writeUTF((new Date()).toString()+"#"+midlet.getMensaje()+"@"+LocalDevice.getLocalDevice().getFriendlyName());
                out.flush();

                String s = in.readUTF();
                midlet.setMensaje(s);

                cancelar(); //cancelamos las busquedas

            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            finally
            {
                try {
                    if (in != null)
                    {
                        in.close();
                    }
                    if (out != null)
                    {
                        out.close();
                    }
                    if (connection != null)
                    {
                        connection.close();
                    }
                } catch (IOException e) {}
            }
        }
    }

    public void startSearchServices(int dispositivo) throws IOException
    {
        RemoteDevice rd=(RemoteDevice)dispositivos.elementAt(dispositivo);

        try
        {
            int transId = agente.searchServices(ATRIBUTOS, SERVICIOS, rd, this);
            mensaje="Conectando con el servidor.";
            dispositivosServiciosId.addElement(new Integer(transId));
        }
        catch(BluetoothStateException e)
        {
            System.out.println("No se pudo conectar con el servidor.");
        }
    }

    public void cancelar()
    {
        if(agente!=null)
        {
            agente.cancelInquiry(this);

            Enumeration aux = dispositivosServiciosId.elements();
            Integer i;

            while(aux.hasMoreElements())
            {
                i = (Integer) aux.nextElement();
                agente.cancelServiceSearch(i.intValue());
            }
        }
    }
    /**
     * Retoran un listado con los dispositivos bluetooth que se encontraron.
     * @return String que representa un listado de los dispositivos bluetooth.
     * @throws IOException
     */
    public String getDispositivos() throws IOException {
        String r = "";
        if (dispositivos != null && dispositivos.size() > 0) {
            r += "Dispositivos Bluetooth = \n";
            int i;
            for (i = 0; i < dispositivos.size(); i++) {
                r += ((RemoteDevice) dispositivos.elementAt(i)).getFriendlyName(true) + "\n";
            }

            return r;
        }

        r = "No hay información de dispositivos bluetooth.";
        return r;
    }

    public void setListaDispositivos() throws IOException
    {
        int i;
        for(i=0;i<dispositivos.size();i++)
        {
            midlet.setDispositivoLista(((RemoteDevice)dispositivos.elementAt(i)).getFriendlyName(true));
        }
    }

    /**
     * @return the isReady
     */
    public boolean isIsReady() {
        return isReady;
    }

    /**
     * @param isReady the isReady to set
     */
    public void setIsReady(boolean isReady) {
        this.isReady = isReady;
    }

    /**
     * @return the mensaje
     */
    public String getMensaje() {
        return mensaje;
    }

    /**
     * @param mensaje the mensaje to set
     */
    public void setMensaje(String mensaje) {

        this.mensaje = mensaje;
        System.out.println(mensaje);
    }

    public String getNombreDispositivo(int i)
    {
        if(i>0 && i<dispositivos.size())
        {
            try
            {
                return ((RemoteDevice)dispositivos.elementAt(i)).getFriendlyName(false);
            }
            catch(Exception e){ }
        }
        return null;
    }
    
/***********/    
    /*
     * REtorna una lista de los archivos compartidos
     */
    public String darArchivosCompartidos()
    {
        String arch="";
        
        if(archivos_compartidos == null)
        {
            return "No hay Archivos Para Compartir";
        }
        else {
            for (int i = 0; i < archivos_compartidos.size(); i++) {
                 Archivo a=(Archivo)archivos_compartidos.get(i);
                 arch+= a.getNombre();
                 arch+= " - ";
            }
            return arch;
        }
    }
    
}
